package com.zx.service;

import java.io.Serializable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

import com.zx.vo.User;


@Service
public class RedisDemoServce {

    @Autowired
    private RedisTemplate<?, ?> redisTemplate;
    
    public void test() {
//    	redisTemplate.opsForValue().setIfAbsent(key, value)
//    	redisTemplate.opsForValue().setIfPresent(key, value)
//    	redisTemplate.
    }
//	注解介绍
//
//	　　@Cacheable（根据方法的请求参数对其结果进行缓存）
//	　　　　key:缓存的key，可以为空，如果指定要按照SpEL表达式编写，如果不指定，则缺省按照方法的所有参数进行组合（如：@Cacheable(value="user",key="#username")）
//	　　　　value:缓存的名称，在Spring 配置文件中定义，必须指定至少一个（如：@Cacheable(value="user")或者@Cacheable(value={"user1","user2"})
//	　　　　condition:缓存的条件，可以为空，使用SpEL编写，返回true或者false，只有为true才进行缓存（如：@Cacheable(value="user",key="#id",condition="#id < 10")）
//
//	　　@CachePut（根据方法的请求参数对其结果进行缓存，和@Cacheable不同的是，它每次都会触发真实方法的调用）
//
//	　　@CacheEvict（根据条件对缓存进行清空）
//	　　　　allEntries:是否清空所有缓存内容，缺省为false，如果指定为true，则方法调用后将立即清空所有缓存(如：@CacheEvict(value="user",key="#id",allEntries=true))
//	　　　　beforeInvocation:是否在方法执行前就清空，缺省为false，如果指定为true，则在方法还没有执行的时候就清空缓存，缺省情况下，如果方法抛出异常，则不会清空缓存（如：@CacheEvict(value="user",key="#id",beforeInvocation)）
	    
//	根据条件操作缓存
//	　　根据条件操作缓存内容并不影响数据库操作，条件表达式返回一个布尔值，true/false，当条件为true，则进行缓存操作，否则直接调用方法返回结果。
//
//	　　　　长度：@CachePut(value="user",key="#user.id",condition="#user.username.legnth() < 10") 只缓存用户名长度小于10的数据
//	　　　　大小：@Cacheable(value="user",key="#id",condition="#id < 10") 只缓存id小于10的数据
//	　　　　组合：@Cacheable（value="user",key="#user.username.concat(#user.password)")
//	　　　　提前操作：@CacheEvict(value="user",allEntries=true,beforeInvocation=true)加上beforeInvocation=true后，不管内部是否报错，缓存都将被清除，默认情况为false。
	

    @Cacheable(value="t_user",key="#id")
    public User getById(int id) {
        System.out.println("进入查询方法");
        return null;
    }

    @CacheEvict(value="t_user",key="#id")
    public int delete(Integer id){
        System.out.println("进入删除方法");
        return 0;
    }

    @CachePut(value="t_user",key="#user.id")
    public int update(User user) {
        System.out.println("进入修改方法");
        return 0;
    }
    
    public boolean setIfAbsent(final String key, final Serializable value, final long exptime) {
        Boolean b = (Boolean) redisTemplate.execute(new RedisCallback<Boolean>() {
            @SuppressWarnings({ "rawtypes", "unchecked" })
			@Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer valueSerializer = redisTemplate.getValueSerializer();
                RedisSerializer keySerializer = redisTemplate.getKeySerializer();
                Object obj = connection.execute("set", keySerializer.serialize(key), 
                                    valueSerializer.serialize(value),
                                    "NX".getBytes(), 
                                    "EX".getBytes()
//                                    , 
//                                    Protocol.toByteArray(exptime)
                                    );
                return obj != null;
            }
        });
        return b;
    }
}
